package com.ids.transfer.data;

import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.HashMap;
import org.w3c.dom.Element;
import com.ids.transfer.config.Constant;
import com.ids.transfer.util.StrCharUtil;
import com.ids.transfer.util.XmlUtils;

/**
 * this class is used of reading XML file and parsering XML File. and save the
 * related information to HashMap or other Type. 
 * 1.先不考虑加密情况 
 * 2.不考虑WebService
 * 3.任务先不考虑类引用
 */
public class XmlParse {

	public XmlParse() {

	}

	/**
	 * 根据数据源名称，取得dataSource节点对应的HashMap
	 * 数据源属性设定,参数意义如下: 
	 * name:数据源名称 （必须设定） 
	 * url：数据源连接URL （必须设定） 
	 * username：登陆数据库用户名（必须设定） 
	 * password：登陆数据库密码 （必须设定） 
	 * connection-driver：数据库驱动 （必须设定）
	 * dbtype：数据库类型，保留 （可选，默认ORACLE）
	 * 
	 * @param xmlFilename
	 *            XML文件名路径
	 * @param dsname
	 *            数据源名称
	 * @return 该数据源的属性信息,存在在HashMap中
	 * @throws java.lang.Exception
	 */
	public static HashMap<String, String> getDataSourceInfo(String xmlFilename,
			String dsname) throws Exception {
		HashMap<String, String> map = new HashMap<String, String>();
		Element dsRoot = getRoot(xmlFilename);
		Element dl = (Element) dsRoot.getElementsByTagName("data-sources")
				.item(0);
		int leng = dl.getElementsByTagName("data-source").getLength();
		for (int i = 0; i < leng; i++) {
			Element ds = (Element) dl.getElementsByTagName("data-source").item(
					i);
			if (ds.getAttribute("name").equals(dsname)) {
				map.put("name", ds.getAttribute("name"));
				map.put("url", ds.getAttribute("url"));
				map.put("username", ds.getAttribute("username"));
				map.put("password", ds.getAttribute("password"));
				map.put("connection-driver",
						ds.getAttribute("connection-driver"));
				map.put("endpoint", ds.getAttribute("endpoint"));
				map.put("dbtype", ds.getAttribute("dbtype"));
				return map;
			}
		}
		return null;
	}

	/**
	 * 得到源数据源连接
	 * 
	 * @param dsMap
	 *            有关JDBC连接的参数信息
	 * @return JDBC连接
	 * @throws java.lang.Exception
	 */
	public static Connection getConn(HashMap<String, String> dsMap)
			throws Exception {
		String dbUrl = "", dbUser = "", dbPwd = "", dbDriver = "", dbType = "ORACLE";
		dbUrl = (String) dsMap.get("url");
		dbUser = (String) dsMap.get("username");
		dbPwd = (String) dsMap.get("password");
		dbDriver = (String) dsMap.get("connection-driver");
		dbType = (String) dsMap.get("dbtype");
		Connection conn = null;
		Class.forName(dbDriver);
		//
		conn = DriverManager.getConnection(dbUrl, dbUser, dbPwd);
		return conn;
	}

	/**
	 * 获得根
	 * 
	 * @param xmlFilename
	 *            xml文件所在路径
	 * @return 根节点的Element
	 */
	public static Element getRoot(String xmlFilename) {
		try {
			URL dataXmlUrl;
			Element dataRoot;
			dataXmlUrl = XmlParse.class.getClassLoader()
					.getResource(xmlFilename);
			dataRoot = XmlUtils.loadDocument(dataXmlUrl);
			return dataRoot;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 跟据TaskId取得任务
	 * 任务的属性信息如下: 
	 * etra-class:任务的实现类标签 （可定义多个） name,class： 
	 * （必须设定） id:任务号 （必须设定）
	 * name：任务名称 （必须设定） 
	 * system：所属系统 （保留） 
	 * space：数字 （可选） 
	 * unit：单位 （可选） 
	 * srcds：源数据源 （必须设定） 
	 * desds：目的数据源 （必须设定） 
	 * maxretrynum：最大错误重抽次数 （可选）
	 *  batchnum：一次性批处理记录条数 （可选） 
	 *  starttime：任务开始执行时间 （可选）
	 * 
	 * @param filepath
	 *            XML文件所在路径
	 * @param taskid
	 *            任务号
	 * @return 该任务的属性信息的Hashmap
	 * @throws java.lang.Exception
	 */
	public static HashMap<String,Object> getTaskInfo(String filepath, String taskid)
			throws Exception {
		HashMap<String,Object> resMap = new HashMap<String,Object>();
		Element dataRoot = getRoot(filepath);
		Element tasksEl = (Element) dataRoot.getElementsByTagName("tasks")
				.item(0);
		int ileng = tasksEl.getElementsByTagName("task").getLength();
		for (int i = 0; i < ileng; i++) {
			Element task = (Element) tasksEl.getElementsByTagName("task").item(i);
			if (task.getAttribute("id").equals(taskid)) {
				resMap.put("name", task.getAttribute("name"));
				resMap.put("id", task.getAttribute("id"));
				resMap.put("system", task.getAttribute("system"));
				resMap.put("space", task.getAttribute("space"));
				resMap.put("unit", task.getAttribute("unit"));
				resMap.put("maxretrynum", task.getAttribute("maxretrynum"));
				resMap.put("batchnum", task.getAttribute("batchnum"));
				resMap.put("starttime", task.getAttribute("starttime"));
				resMap.put("endtime", task.getAttribute("endtime"));
				resMap.put("cronexpression", task.getAttribute("cronexpression"));
				resMap.put("srcds", task.getAttribute("srcds"));
				resMap.put("desds", task.getAttribute("desds"));
				resMap.put("auto", task.getAttribute("auto"));
				//要考虑到文本也是节点
				int itemLength= task.getElementsByTagName("item").getLength();
				HashMap<String,String> cmap=new HashMap<String,String>();
				for(int item=0;item<itemLength;item++){
					Element itemElement = (Element) task.getElementsByTagName("item").item(item);
					cmap.put("class"+item,itemElement.getAttribute("class"));
				}
				resMap.put("ecmap", cmap);
				
			}
		}
		return resMap;
	}

	/**
	 * 一次性读入所有任务
	 * 取得所有任务的ID,不取其它参数
	 * @return
	 * @throws java.lang.Exception
	 */
	public static HashMap<String,String> getAllTaskId() throws Exception {
		HashMap<String,String> resMap = new HashMap<String,String>();
		Element dataRoot = getRoot(Constant.XMLFILEPATH);
		Element tasksEl = (Element) dataRoot.getElementsByTagName("tasks")
				.item(0);
		int ileng = tasksEl.getElementsByTagName("task").getLength();
		for (int i = 0; i < ileng; i++) {
			Element el = (Element) tasksEl.getElementsByTagName("task").item(i);
			//value预留后用
			resMap.put( el.getAttribute("id"),"Idle");
		}
		return resMap;
	}

	/**
	 * 根据className得到实现类的信息
	 * 主要用到工厂模型-反射思想
	 * 实现类的属性信息如下: 
	 * name:类名称 （必须设定） 
	 * type：实现类全名 （必须设定） 
	 * etra-class-param：定义一系列参数（可定义多个） 
	 * from:源SELECT语句 （必须设定） 
	 * to：目的INSERT语句 （必须设定）
	 * field：源SELECT中需要抽取的字段，用逗号隔开 （可选） 
	 * field_name：用作特殊用途 （可选） 
	 * field_type：用作特殊用途 （可选）
	 * 结构如下
	 * <etra-classes>
	 *	<etra-class name="" type="">
	 *		<etra-module enable="">
	 *			<etra-class-param name=""
					value="" />
			</etra-module>
		</etra-class>
		</etra-classes>
	 * @param filepath
	 *            XML所在路径
	 * @param classname
	 *            实现类名称
	 * @return 该实现类的属性信息HashMap
	 * 		as result for:name,type,modulenum,pmap{m1_from,select * from XXXX}
	 * @throws java.lang.Exception
	 */
	public static HashMap<String,Object> getImpClassInfo(String filepath, String classname)
			throws Exception {
		HashMap<String,Object> resMap = new HashMap<String,Object>();
		Element dataRoot = getRoot(filepath);
		Element cEl = (Element) dataRoot.getElementsByTagName("items")
				.item(0);
		int ileng = cEl.getElementsByTagName("item").getLength();
		int moduleCount = 0;
		for (int i = 0; i < ileng; i++) {
			Element el = (Element) cEl
				.getElementsByTagName("item").item(i);
			if (el.getAttribute("name").equals(classname)) {
				//类名
				resMap.put("name", el.getAttribute("name"));
				//类全名
				resMap.put("type", el.getAttribute("type"));
				int leng = el.getElementsByTagName("item-module").getLength();
				//用一个嵌套的MAP来装载etra-module
				HashMap<String,String> pmap = new HashMap<String,String>();
				for (int j = 0; j < leng; j++) {
					Element modulemap = (Element) el.getElementsByTagName(
							"item-module").item(j);
					int paramNum = modulemap.getElementsByTagName(
							"item-parameter").getLength();
					String str = StrCharUtil.formatNullStr(modulemap
							.getAttribute("enable"));
					if (!str.equals("false")) {
						for (int k = 0; k < paramNum; k++) {
							Element tmp = (Element) modulemap
									.getElementsByTagName("item-parameter")
									.item(k);
							//map{m1_from,select * from XX}
							pmap.put(
									"m" + (moduleCount) + "_"
											+ tmp.getAttribute("name"),
									tmp.getAttribute("value"));
							//{m1_from_pk,deptno}
							pmap.put(
									"m" + (moduleCount) + "_"
											+ tmp.getAttribute("name")+ "_pk",
									tmp.getAttribute("primarykey"));
							
						}
						++moduleCount;
					}
				}
				//一共需要有多少个SQL
				resMap.put("modulenum", moduleCount);
				resMap.put("pmap", pmap);
				return resMap;
			}
		}
		return null;
	}

	public static void main(String[] args) {
		try {
			HashMap<String, Object>  map=XmlParse.getTaskInfo(Constant.XMLFILEPATH, "genTask");
			for (String key : map.keySet()) {
				System.out.print(key+":");
				System.out.println(map.get(key));
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}